package com.yjt.javatest.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yjt.javatest.dao.*;
import com.yjt.javatest.entity.*;
import com.yjt.javatest.entity.*;
import com.yjt.javatest.entity.DTO.QuestionTestDTO;
import com.yjt.javatest.entity.vo.*;
import com.yjt.javatest.entity.DTO.UpdateQuestionTestDTO;
import com.yjt.javatest.entity.vo.CompleteQuestion;
import com.yjt.javatest.entity.vo.StudentTestVo;
import com.yjt.javatest.entity.vo.TestNameVo;
import com.yjt.javatest.entity.vo.TestVo;
import com.yjt.javatest.service.TestService;
import com.yjt.javatest.utils.*;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import com.yjt.javatest.utils.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


@Service //注册成容器组件
@Transactional(rollbackFor = Exception.class)
public class TestServiceImpl extends ServiceImpl<TestMapper, Test> implements TestService {
    @Resource
    TestMapper testMapper;
    @Resource
    QuestionMapper questionMapper;
    @Resource
    QuestionTestMapper questionTestMapper;
    @Resource
    StudentTestMapper studentTestMapper;
    @Resource
    TestLibMapper testLibMapper;
    @Resource
    QuestionTestLibMapper questionTestLibMapper;

    //锁
    private static final ReentrantLock Lock= new ReentrantLock();//创建一把最简单的线程安全的锁

    public static String parse(String content, Map<String, String> kvs) {
        String pattern = "\\$\\{(.*?)}";
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(content);
        StringBuffer sr = new StringBuffer();
        while (m.find()) {
            String group = m.group();
            m.appendReplacement(sr, kvs.get(group));
        }
        m.appendTail(sr);
        return sr.toString();
    }

    public List<CompleteQuestion> generateQuestions(List<Question> questions) {
        //存储返回结果
        List<CompleteQuestion> reQues=new ArrayList<>();
        //******************生成一份带问题，分数的卷子*******************
        for (Question question : questions) {

            CompleteQuestion tempQues = new CompleteQuestion();
            //获取问题内容
            JSONObject tempJSON = JSONObject.parseObject(question.getContent());
            //设置所有问题共有的部分
            tempQues.setImage(question.getImage());
            tempQues.setScore(question.getScore());
            tempQues.setType(question.getType());
            //第一类型问题 tempQues.setQuestion(tempJSON.getString("content"));
            if (question.getType() == 1) {
                JSONArray options = tempJSON.getJSONArray("option");
                List<String> tempList = new ArrayList<>();
                for (int i = 0; i < options.size(); i++) {
                    JSONObject jsonObject = options.getJSONObject(i);
                    tempList.add(jsonObject.getString("option"));
                }
                tempQues.setOptions(tempList);
//                tempQues.setSize(options.size());
            }
            else {
                //第二类问题
                JSONObject param = tempJSON.getJSONObject("param");
                Map<String, String> ma = new HashMap<>();
                Map<String, Object> params = new HashMap<>();
                params.put("pi", 3.1415926535);
                if(!Objects.isNull(param)) {
                    for (Map.Entry<String, Object> entry : param.entrySet()) {
                        String key = "${" + entry.getKey() + "}";
                        JSONObject paramJs = (JSONObject) entry.getValue();
                        Map<String, Object> randomMap;
                        randomMap = RandomValue.randomValue(paramJs);
                        ma.put(key, randomMap.get("value").toString());
                        params.put(entry.getKey(), randomMap.get("value"));
                    }
                }
                tempQues.setQuestion(parse(tempJSON.getString("content"), ma));
                tempQues.setParams(params);
                if(question.getType() == 2) { //判断题目公式是否正确
                    String formula = tempJSON.getString("formula");
                    AviatorEvaluator.compile(formula, true);
                }
                if (question.getType() == 3) {
                    String formula = tempJSON.getString("formula");
                    Expression compiledExp = AviatorEvaluator.compile(formula, true);
                    Object result = compiledExp.execute(params);
                    String errorFormula = tempJSON.getString("errorFormula");
                    Object err_result = "";
                    if(!Objects.isNull(errorFormula) && !errorFormula.isEmpty()) {
                        Expression err_compiledExp = AviatorEvaluator.compile(errorFormula, true);
                        err_result = err_compiledExp.execute(params);
                    }
                    JSONArray option = tempJSON.getJSONArray("option");
                    List<String> tempList = new ArrayList<>();
                    if(!Objects.isNull(option)) {
                        for (int i = 0; i < option.size(); i++) {
                            JSONObject jsonObject = option.getJSONObject(i);
                            tempList.add(jsonObject.getString("option").replaceFirst("\\$\\{formula}", result.toString())
                                    .replaceAll("\\$\\{errorFormula}", err_result.toString()));
                        }
                    }
                    tempQues.setOptions(tempList);
                }
                if (question.getType() == 4) {
                    //第四类问题
                    List<String> answer_list = (List<String>) tempJSON.getObject("answer_list", List.class);
                    tempQues.setAnswerList(answer_list);
//                    tempQues.setSize(answer_list.size());
                }
                if (question.getType() == 5) {
                    //遍历所有option_params
                    JSONObject optionParam = tempJSON.getJSONObject("option_param");
                    List<List<Object>> optionParamList = new ArrayList<>();
                    List<String> nameList = new ArrayList<>();
                    for (Map.Entry<String, Object> entry : optionParam.entrySet()) {
                        List<Object> object = optionParam.getObject(entry.getKey(), List.class);
                        nameList.add("${" + entry.getKey() + "}");
                        optionParamList.add(object);
                    }
                    //生成所有组合
                    List<String> optionList = new ArrayList<>();
                    List<List<Object>> descartes = ListUtil.getDescartes(optionParamList);
                    for (List<Object> deescalate : descartes) {
                        String option = tempJSON.getString("option");
                        for (int j = 0; j < nameList.size(); j++) {
                            option = option.replace(nameList.get(j), deescalate.get(j).toString());
                        }
                        optionList.add(option);
                    }
                    tempQues.setOptions(optionList);
//                    tempQues.setSize(optionList.size());
                }
                if (question.getType() == 6) {
                    tempQues.setAnswerList(tempJSON.getObject("answer_list", List.class));
                    tempQues.setQuestion(tempJSON.getString("content"));
                }
            }
            tempQues.setQuestionId(question.getQuestionId());
            reQues.add(tempQues);
        }
        //*************************************************
//        JSONObject reJson=new JSONObject();
//        reJson.put("count",questions.size());
//        reJson.put("questionList",reQues);
        return reQues;

    }
    /**
     * //回滚机制,Exception.class任何异常都回滚,如果执行过程中发生异常情况，就会终止操作，
     * 且之前的操作也不提交，考虑安全性，也叫接口的幂等性
     */
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    @Override
    public APIResponse createTest(Test test) {
        Date startAt = test.getStartAt();
        Date endAt = test.getEndAt();
        test.setIsDeleted(false);
        test.setTimeLimit(1000); //目前无用，不用管
        if(startAt.before(new Date())){
            return APIResponse.error("开始时间不能在当前时间之前");
        }
        if(endAt.before(startAt)){
            return APIResponse.error("结束时间不能在开始时间前");
        }
        Lock.lock();
        try{
            test.setUserId(SecurityUtil.getUserId());
            testMapper.insert(test);
            return APIResponse.success("test 创建成功");
        }catch (Exception e){
            e.printStackTrace();
        }
        finally {
            Lock.unlock();
        }
        return APIResponse.error(ErrorCode.INSERT_DATABASE_ERROR);
    }

    @Override
    public APIResponse getTests() {
        try {
            QueryWrapper<Test> wrapper = new QueryWrapper<>();
            wrapper .eq("user_id",SecurityUtil.getUserId())
                    .eq("is_deleted",0);
            List<Test> tests = testMapper.selectList(wrapper);
            return APIResponse.success(tests);
        } catch (Exception e) {
            e.printStackTrace();
            return APIResponse.error("获取当前用户所有测试失败");
        }
    }

    @Override
    public APIResponse updateTest(Test test) {
        Test oldTest = testMapper.selectById(test.getTestId());
        SecurityUtil.checkUserAuthority(oldTest.getUserId(), "修改测试失败,权限不够");
        test.setUserId(SecurityUtil.getUserId());
        if(test.getUserId().compareTo(oldTest.getUserId()) != 0) {
            return APIResponse.error("修改测试失败，测试所属用户不对");
        }
        testMapper.updateById(test);
        return APIResponse.success("更新成功");
    }


    @Override
    public APIResponse addQuestionToTest(Integer questionId, Integer testId, Integer score) {
        Question question = questionMapper.selectById(questionId);
        Test test = testMapper.selectById(testId);

        if(Objects.isNull(question) || Objects.isNull(test)) {
            return APIResponse.error("无该题目或测试！");
        }

        SecurityUtil.checkUserAuthority(test.getUserId(), "添加测试失败");
        SecurityUtil.checkUserAuthority(question.getUserId(), "添加测试失败");
        if(test.getStartAt().before(new Date())) {
            return APIResponse.error("测试已经开始,不允许添加问题！");
        }
        synchronized (Lock) {

            QueryWrapper<QuestionTest> wrapper = new QueryWrapper<>();
            wrapper.eq("question_id", questionId)
                    .eq("test_id", testId);
            QuestionTest questionTest = questionTestMapper.selectOne(wrapper);
            if (!Objects.isNull(questionTest)) {
                return APIResponse.error("该题目已在该测试中");
            }

            questionTest = new QuestionTest();
            questionTest.setQuestionId(Long.valueOf(questionId));
            questionTest.setTestId(Long.valueOf(testId));
            Long order = questionTestMapper.getMaxOrderByTestId(Long.valueOf(testId));
            if(Objects.isNull(order)) {
                order = -1L;
            }
            Long maxOrder = questionTestMapper.getMaxOrderByTestId(Long.valueOf(testId));
            if(maxOrder == null) {
                maxOrder = 0L;
            }
            if(score == null) {
                score = question.getScore();
            }
            questionTest.setScore(score);
            questionTest.setOrder(maxOrder + 1);
            questionTestMapper.insert(questionTest);
        }

        return APIResponse.success("添加成功");
    }

    @Override
    public APIResponse deleteQuestionFromTest(Integer questionId, Integer testId) {
        Test test = testMapper.selectById(testId);
        SecurityUtil.checkUserAuthority(test.getUserId());
        if(test.getStartAt().before(new Date())) {
            return APIResponse.error("测试已经开始,不允许添加问题！");
        }
        QueryWrapper<QuestionTest> wrapper = new QueryWrapper<>();
        wrapper .eq("question_id",questionId)
                .eq("test_id",testId);
        QuestionTest questionTest = questionTestMapper.selectOne(wrapper);
        if(Objects.isNull(questionTest)) {
            return APIResponse.error("该题目不在该测试中");
        }
        questionTestMapper.deleteById(questionTest);
        return APIResponse.success("删除成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public APIResponse studentGetTestById(Long id) {
        TestVo test = new TestVo(testMapper.selectById(id));
        //如果未开放，则不能查看测试
        if (test.getStartAt().after(new Date())) {
            return APIResponse.error("该测试尚未开放");
        }
        StudentTestDao studentTestDao = studentTestMapper.getByTestIdAndUserId(id, SecurityUtil.getUserId());
        StudentTest studentTest = new StudentTest();
        synchronized (SecurityUtil.getUserId()) {
            //如果未获取过测试，则生成一份题目并创建studentTest记录
            if(Objects.isNull(studentTestDao)) {
                if(test.getEndAt().before(new Date())) {
                    return APIResponse.error("该测试已结束！");
                }
                //生成题目
                List<CompleteQuestion> completeQuestions = generateQuestions(questionMapper.getQuestionsByTestId(id));
                if(!test.getIsOrdered()) {
                    Collections.shuffle(completeQuestions);
                }
                JSONArray correctAnswers = new JSONArray();
                for (CompleteQuestion completeQuestion : completeQuestions) {
                    JSONObject json = new JSONObject(completeQuestion.getParams());
                    correctAnswers.add(json);
                    completeQuestion.setParams(null);
//                    completeQuestion.setAnswerList(null);
                }
                //创建studentTest
                studentTest = new StudentTest();
                studentTest.setTestId(id);
                studentTest.setUserId(SecurityUtil.getUserId());
                studentTest.setQuestions(completeQuestions);
                studentTest.setCreateAt(new Date());
                studentTest.setCorrectAnswers(correctAnswers);
                studentTest.setScore(0);
                studentTest.setTitle(test.getTitle());
                studentTestMapper.insert(studentTest, JSON.toJSONString(completeQuestions), JSON.toJSONString(correctAnswers));
            } else {
                studentTest = studentTestDao.toStudentTest();
            }
            test.setCompleteQuestions(studentTest.getQuestions());
        }
        return APIResponse.success(test);
    }


    @Override
    public APIResponse teacherGetTestById(Long id) {
        TestVo test = new TestVo(testMapper.selectById(id));
        test.setRawQuestions(questionMapper.getQuestionsByTestId(id));
        return APIResponse.success(test);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public APIResponse changeQuestionOrder(UpdateQuestionTestDTO data) {
        QueryWrapper<QuestionTest> wrapper = new QueryWrapper<>();
        wrapper .eq("test_id", data.getTestId());
        Test test = testMapper.selectById(data.getTestId());
        SecurityUtil.checkUserAuthority(test.getUserId());
        if(test.getStartAt().before(new Date())) {
            return APIResponse.error("该测试已经开始，不能再修改！");
        }
        synchronized (SecurityUtil.getUserId()) {
            List<QuestionTest> questionTests = questionTestMapper.selectList(wrapper);
            //获取题目原顺序位置
            Long oldOrder = null;
            for (QuestionTest questionTest : questionTests) {
                if (questionTest.getQuestionId().compareTo(data.getQuestionId()) == 0) {
                    oldOrder = questionTest.getOrder();
                    break;
                }
            }
            if (oldOrder == null) {
                return APIResponse.error(ErrorCode.SELECT_DATABASE_ERROR, "无该题目");
            }
            Long delta = oldOrder > data.getOrder() ? 1L : -1L;
            Long mn = Math.min(data.getOrder(), oldOrder), mx = Math.max(data.getOrder(), oldOrder);
            //修改原顺序位置与现在的顺序位置之间的题目的顺序
            for (QuestionTest questionTest : questionTests) {
                if (questionTest.getQuestionId() >= mn && questionTest.getQuestionId() <= mx) {
                    questionTest.setOrder(questionTest.getOrder() + delta);
                    if (questionTest.getQuestionId().compareTo(data.getQuestionId()) == 0) {
                        questionTest.setOrder(data.getOrder());
                    }
                    questionTestMapper.updateById(questionTest);
                }
            }
        }

        return APIResponse.success("修改成功");

    }
    @Override
    public APIResponse teacherPreviewTest(Long id) {
        List<CompleteQuestion> completeQuestions = generateQuestions(questionMapper.getQuestionsByTestId(id));
        return APIResponse.success(completeQuestions);
    }

    @Override
    public APIResponse teacherPreviewQuestion(Long id) {
        List<Question> questions = new ArrayList<>();
        Question question = questionMapper.selectById(id);
        questions.add(question);
        List<CompleteQuestion> completeQuestions = generateQuestions(questions);
        return APIResponse.success(completeQuestions.get(0));
    }

    @Override
    public APIResponse finishTest(Long id) {
        Test test = testMapper.selectById(id);
        SecurityUtil.checkUserAuthority(test.getUserId());
        if(test.getEndAt().before(new Date())) {
            return APIResponse.success("已经处于结束");
        }
        test.setEndAt(new Date());
        testMapper.updateById(test);
        return APIResponse.success("开放成功");
    }

    @Override
    public APIResponse createTestByTestLibId(Long testLibId, TestInfo testInfo) {
        Test test = new Test();
        test.setTitle(testInfo.getTitle());
        test.setDescription(testInfo.getTitle());
        test.setIsOrdered(testInfo.getIsOrdered());
        test.setStartAt(testInfo.getStartAt());
        test.setEndAt(testInfo.getEndAt());
        test.setAnswerReleaseAt(testInfo.getAnswerReleaseAt());
        test.setUserId(SecurityUtil.getUserId());
        APIResponse apiResponse = createTest(test);
        if(apiResponse.getCode() != 200) {
            return apiResponse;
        }
        List<QuestionTestDTO> questionTests = questionTestLibMapper.getQuestionsByTestLibId(testLibId);
        questionTestMapper.addQuestions(test.getTestId(), questionTests);
        return APIResponse.success(test);
    }


    @Override
    synchronized public APIResponse setOpenStatusOn(Long id) {
        Test test = testMapper.selectById(id);
        SecurityUtil.checkUserAuthority(test.getUserId());
        if(test.getStartAt().before(new Date())) {
            return APIResponse.success("已经处于开放状态");
        }
        test.setStartAt(new Date());
        testMapper.updateById(test);
        return APIResponse.success("开放成功");
    }

    @Override
    synchronized public APIResponse setAnswerReleaseStatus(Long id) {
        Test test = testMapper.selectById(id);
        SecurityUtil.checkUserAuthority(test.getUserId());
        if(test.getAnswerReleaseAt().before(new Date())) {
            return APIResponse.success("已经处于公布状态");
        }
        //公布时间应该位于结束时间之后
        if(test.getEndAt().after(new Date())) {
            return APIResponse.error("公布时间过早！应处于结束时间之后!");
        }
        test.setAnswerReleaseAt(new Date());
        testMapper.updateById(test);
        return APIResponse.success("公布成功");
    }

    @Override
    synchronized public APIResponse setStartTime(Long id, Date startTime) {
        Test test = testMapper.selectById(id);
        SecurityUtil.checkUserAuthority(test.getUserId());
        if(test.getStartAt().before(new Date())) {
            return APIResponse.error("已经开放！不允许修改开放时间！");
        }
        if(startTime.after(test.getEndAt())) {
            return APIResponse.error("开始时间不能位于结束时间之后！");
        }
        if(startTime.after(new Date())) {
            return APIResponse.error("开放时间不能位于现在之前！");
        }
        test.setStartAt(startTime);
        testMapper.updateById(test);
        return APIResponse.success("修改开放时间成功");
    }
    @Override
    synchronized public APIResponse setEndTime(Long id, Date endTime) {
        Test test = testMapper.selectById(id);
        SecurityUtil.checkUserAuthority(test.getUserId());
        if(endTime.after(test.getEndAt())) {
            return APIResponse.error("已经结束！不允许修改结束时间！");
        }
        if(endTime.after(new Date())) {
            return APIResponse.error("结束时间不能位于现在之前！！");
        }
        test.setEndAt(endTime);
        testMapper.updateById(test);
        return APIResponse.success("修改结束时间成功");
    }

    @Override
    synchronized public APIResponse setAnswerReleaseTime(Long id, Date answerReleaseTime) {
        Test test = testMapper.selectById(id);
        SecurityUtil.checkUserAuthority(test.getUserId());
        if(test.getAnswerReleaseAt().before(new Date())) {
            return APIResponse.error("已经公布！！不允许修改公布时间！");
        }
        if(answerReleaseTime.after(new Date())) {
            return APIResponse.error("公布时间不能位于现在之前！！");
        }
        if(answerReleaseTime.before(test.getEndAt())) {
            return APIResponse.error("公布时间不能位于结束时间之前！");
        }
        if(answerReleaseTime.before(test.getStartAt())) {
            return APIResponse.error("公布时间不能位于开放时间之前！");
        }
        test.setAnswerReleaseAt(answerReleaseTime);
        testMapper.updateById(test);
        return APIResponse.success("修改公布时间成功");
    }

    @Override
    public APIResponse getReleasedTests(Integer teacherId) {
        QueryWrapper<Test> wrapper = new QueryWrapper<>();
        wrapper .eq("user_id", teacherId)
                .eq("open_status", 1);
        List<Test> tests = testMapper.selectList(wrapper);
        return APIResponse.success(tests);
    }

    @Override
    public APIResponse addQuestionsToTest(Long testId, List<QuestionTestDTO> questionInfo) {
        Test test = testMapper.selectById(testId);
        if(test.getStartAt().before(new Date())) {
            return APIResponse.error("该测试已经开始,不能再修改！");
        }
        Integer num = questionTestMapper.addQuestions(testId, questionInfo);
        if(num != questionInfo.size()) {
            return APIResponse.error("批量插入失败！");
        }
        return APIResponse.success("批量插入成功");
    }


    @Override
    public APIResponse exportStudentInfoByTestIds(List<Integer> testIds, Integer opt, HttpServletResponse response) {
        //testId对应表格位置为传入位置
        HashMap<Integer, Integer> indexMap = new HashMap<>();
        for(int i = 0; i < testIds.size(); i++) {
            indexMap.put(testIds.get(i), i);
        }
        ArrayList<Integer> scoreTemplate =  new ArrayList<>(testIds.size()); //成绩列表模板
        for(int i = 0; i < testIds.size(); i++) {
            if(opt == 0 || opt == 1) {
                scoreTemplate.add(0);
            } else {
                scoreTemplate.add(null);
            }
        }
        //获取学生成绩信息
        List<StudentTestVo> infos = studentTestMapper.getStudentTestInfoByTestIds(testIds);
        HashMap<Integer, List<Integer> > scoreMap = new HashMap<>(); //userId对应成绩列表,顺序为testIds顺序
        HashMap<Integer, String> usernameMap = new HashMap<>(); //userId对应name映射
        for (StudentTestVo info : infos) {
            scoreMap.putIfAbsent(info.getUserId(), (List<Integer>) scoreTemplate.clone());
            scoreMap.get(info.getUserId()).set(indexMap.get(info.getTestId()), info.getScore());
            usernameMap.putIfAbsent(info.getUserId(), info.getName());
        }

        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("sheet1");
        //第一行为考试标题
        Row nameRow = sheet.createRow(0);
        nameRow.createCell(0);
        HashMap<Integer, String> testName = new HashMap<>();
        for (TestNameVo testTitle : testMapper.getTestTitles(testIds)) {
            testName.put(testTitle.getTestId(), testTitle.getTitle());
        }
        for(int i = 0; i < testIds.size(); i++) {
            nameRow.createCell(i + 1).setCellValue(testName.get(testIds.get(i)));
        }

        List<Integer> totalScore = new ArrayList<>(testIds.size());
        List<Integer> totalNum = new ArrayList<>(testIds.size());
        for(int i = 0;  i < testIds.size(); i++) {
            totalScore.add(0);
            totalNum.add(0);
        }
        int rowNum = 1;

        //设置分数
        for (Map.Entry<Integer, List<Integer>> entry : scoreMap.entrySet()) {
            Row row = sheet.createRow(rowNum++);
            row.createCell(0).setCellValue(usernameMap.get(entry.getKey())); //第一列为用户名
            //设置分数
            for(int i = 0; i < testIds.size(); i++) {
                Cell scoreCell = row.createCell(i + 1);
                Integer score = (entry.getValue().get(i));
                if(!Objects.isNull(score)) {
                    scoreCell.setCellValue(score);
                    totalScore.add(i, score);
                    totalNum.add(i, 1);
                }
            }
        }
        //设置平均分
        Row averageRow = sheet.createRow(rowNum);
        averageRow.createCell(0).setCellValue("平均分");
        for(int i = 0; i < testIds.size(); i++) {
            Double averageScore = Double.valueOf(totalScore.get(i));
            if(totalNum.get(i) != 0) {
                averageScore /= totalNum.get(i);
            }
            averageRow.createCell(i + 1).setCellValue(String.format(".2f",averageScore));
        }

        try {
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=scores.xlsx");
            ServletOutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            return APIResponse.error("导出失败");
        }
        return APIResponse.success("导出成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public APIResponse deleteTest(Integer id) {
        Test test = testMapper.selectById(id);
        if(test.getStartAt().before(new Date())) {
            return APIResponse.error("该测试已经开始,不能再修改！");
        }
        if(Objects.isNull(test)) {
            return APIResponse.error(ErrorCode.NULL_DATA_ERROR,"无该测试");
        }
        SecurityUtil.checkUserAuthority(test.getUserId());
        //用户认证
        testMapper.deleteById(id);
        //因为是逻辑删除，故不删除问题测试表中数据，以便可恢复
        return APIResponse.success("删除成功");
    }

}
